#include<iostream>
#include<vector>
#include<cstdlib>
#include<unistd.h>
#include<pthread.h>
#include<string>
#include<string.h>
using namespace std;
//#define NUM 10
int ticket=100;
class threadData{
public:
    threadData(int number){
        threadname="thread"+to_string(number);
    }
    string threadname;
};

string Tohex(pthread_t tid)
{
    char hex[64];
    snprintf(hex, sizeof(hex), "%p", tid);
    return hex;
}
// void *getTickets(void *arg){//在抢票系统中发现负的的数字还在抢，这说明发生了，重入函数的错误
//     threadData*td=static_cast<threadData*>(arg);
//     while(true){
//         if(ticket>0){
//             usleep(10000);
//             ticket--;
//             cout<<td->threadname<<", get a ticket:"<<ticket<<endl;
//         }
//         else
//             break;
//     }
//     printf("%s ... quit\n",td->threadname.c_str());
//     return nullptr;
// }
// int main()
// {
//     //多进程
//     vector<pthread_t> tids;//保存多进程的tid
//     vector<threadData *>thread_datas;//保存多进程的每个threaddata
//     for(int i=1;i<=NUM;i++){
//         pthread_t tid;
//         threadData*td=new threadData(i);
//         thread_datas.push_back(td);
//         pthread_create(&tid,nullptr,getTickets,thread_datas[i-1]);
//         tids.push_back(tid);
//     }
//     for(auto thread:tids)
//     {
//         pthread_join(thread,nullptr);
//     }
//     for(auto thread_data:thread_datas)
//     {
//         delete thread_data;
//     }
//     return 0;
// }
#define NUM 4

int *p=NULL;
__thread int g_val=100;
void *threadRoutine(void *arg){
    threadData*td=static_cast<threadData*>(arg);
    // pthread_detach(pthread_self());//与主线程分离，主线程不用等结果，但主线程结束时，这个也结束
    // while(1){
    //     cout<<1<<endl;
    // }
    int test_i=0;
    if(td->threadname=="thread2"){
        p=&test_i;
    }
    // while(test_i<10){
    //     cout<<"pid:"<<getpid()<<", tid:"<<Tohex(pthread_self())<<", threadname:"<<td->threadname
    //             <<", test_i:"<<test_i<<"; &test_i:"<<&test_i<<endl;
    //     test_i++;
    // }
    // int i=0;
    //  while(i<10){
    //     cout<<"pid:"<<getpid()<<", tid:"<<Tohex(pthread_self())<<", threadname:"<<td->threadname
    //             <<", g_val:"<<g_val<<"; &g_val:"<<&g_val<<endl;
    //             sleep(1);
    //     i++;
    // }
    return nullptr;
}
int main()
{
    vector<pthread_t>tids;
    vector<threadData*>tds;
    for(int i=0;i<NUM;i++){
        pthread_t tid;
        threadData*td=new threadData(i);
        tds.push_back(td);
        pthread_create(&tid,nullptr,threadRoutine,td);
        tids.push_back(tid);
        usleep(1000);
    }
 
     for(auto td:tds){
        delete td;
    }
    cout << "main thread get a thread local value, val: " << *p << ", &val: " << p << endl;
    // pthread_t tid;
    // threadData*td=new threadData(0);
    // pthread_create(&tid,nullptr,threadRoutine,td);
    // pthread_join(tid,nullptr);
 for (int i = 0; i < tids.size(); i++)
    {
        int n = pthread_join(tids[i], nullptr);
        printf("n = %d, who = 0x%x, why: %s\n", n, tids[i], strerror(n));
    }

    return 0;
}